#!/usr/bin/perl

use strict;
use warnings;
use DBI;
use English qw(-no_match_vars);
use Getopt::Long qw(:config no_ignore_case);
use Time::Local;

sub usage {

    print <<EOF;

Usage:
   $PROGRAM_NAME args, where args are
       --end <YYYY:MM:DD:HH:MM:SS>
EOF
    exit 1;
}

my $args = {};

# Parse the options from the command line
GetOptions( $args, 'end=s' );

for my $arg (qw(end)) {
    usage() unless exists $args->{$arg};
}

my ( $year, $month, $day, $hour, $minute, $second ) =
  $args->{end} =~ /^(\d\d\d\d):(\d\d):(\d\d):(\d\d):(\d\d):(\d\d)$/;
usage() unless $second;
my $end = timelocal( $second, $minute, $hour, $day, $month - 1, $year );

my $dsn = "dbi:mysql:vmstats:localhost";
my $dbh = DBI->connect( $dsn, 'openstack', 'openstack' )
  or die("cannot connect to $dsn using openstack/openstack: $DBI::errstr");
my $sth = $dbh->prepare("delete from vmstats where time > from_unixtime($end)")
  or die $dbh->errstr;

$sth->execute();

$sth = $dbh->prepare("select vm, host, time, cpu from vmstats")
  or die $dbh->errstr;

$sth->execute();

my $vmstats = {};
my $n       = 0;
while ( my ( $vm, $host, $time, $cpu ) = $sth->fetchrow_array() ) {
    $vmstats->{$host}{$time}{vm}{$vm} = $cpu;
    $vmstats->{$host}{$time}{total} = 0
      unless exists $vmstats->{$host}{$time}{total};
    $vmstats->{$host}{$time}{total} += $cpu;
    ++$n;
}

print "fetched $n rows\n";

$sth = $dbh->prepare("update vmstats set cpu = ? where vm = ? and time = ?")
  or die $dbh->errstr;

for my $host ( keys %$vmstats ) {
    print("processing loads of $host\n");
    for my $time ( keys %{ $vmstats->{$host} } ) {
        if ( $vmstats->{$host}{$time}->{total} > 100 ) {
            for my $vm ( keys %{ $vmstats->{$host}{$time}{vm} } ) {
                my $cpu =
                  $vmstats->{$host}{$time}{vm}{$vm} * 100 /
                  $vmstats->{$host}{$time}{total};
                $sth->execute( $cpu, $vm, $time );
            }
        }
    }
}

$dbh->disconnect;
